home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Pascal
/
Snippets
/
ProcPuppy 1.0
/
ProcPuppy.p
< prev
next >
Wrap
Text File
|
1995-01-11
|
8KB
|
251 lines
{ProcPuppy is my simple process management program, related to ProcDoggie but far simpler.}
{My only regret is that TerminateProcess takes so much space. I should probably remove it in}
{order to mae the program simpler, but that makes it less useful as a utility.}
program ProcPuppy;
uses
{$IFC UNDEFINED THINK_PASCAL}
Memtypes, Quickdraw, OSIntf, ToolIntf, PackIntf,
{$ENDC}
Processes, TransSkel;
var
m, infoMenu, switchMenu, terminateMenu: MenuHandle;
dummy: Boolean;
r: Rect;
w: WindowPtr;
const
kMaxProc = 50;
var
iErr: OSErr;
PSN: ProcessSerialNumber;
psnList: array[0..kMaxProc] of ProcessSerialNumber;
pInfo: array[0..kMaxProc] of ProcessInfoRec;
numProc: Integer;
procName: array[0..kMaxProc] of Str255;
curProc: Integer;
procedure About; { Reponse to "About" selection }
begin
end;
{The following function copied from ProcDoggie}
function TerminateProcess (theProcessNum: ProcessSerialNumber): OSErr;
{I don't feel like including several units just for one Apple Event!}
const
typeProcessSerialNumber = 'psn ';
kCoreEventClass = 'aevt';
kAEQuitApplication = 'quit';
kAutoGenerateReturnID = -1; { AECreateAppleEvent will generate a session-unique ID }
kAnyTransactionID = 0; { no transaction is in use }
kAENoReply = $00000001; { Sender doesn't want a reply to event }
kAENormalPriority = $00000000; { Post message at the end of event queue }
kNoTimeOut = -2; { wait until reply comes back, however long it takes }
type
DescType = ResType;
AEDesc = record
descriptorType: DescType;
dataHandle: Handle;
end;
AEAddressDesc = AEDesc; { an AEDesc which contains addressing data }
AEDescList = AEDesc; { a list of AEDesc is a special kind of AEDesc }
AERecord = AEDescList; { AERecord is a list of keyworded AEDesc }
AppleEvent = AERecord; { an AERecord that contains an AppleEvent }
AEEventClass = packed array[1..4] of CHAR;
AEEventID = packed array[1..4] of CHAR;
AESendMode = LONGINT; { Type of parameter to AESend }
AESendPriority = INTEGER; { Type of priority param of AESend }
function AEDisposeDesc (var theAEDesc: AEDesc): OSErr;
inline
$303C, $0204, $A816;
function AECreateDesc (typeCode: DescType; dataPtr: Ptr; dataSize: Size; var result: AEDesc): OSErr;
inline
$303C, $0825, $A816;
function AECreateAppleEvent (theAEEventClass: AEEventClass; theAEEventID: AEEventID; target: AEAddressDesc; returnID: INTEGER; transactionID: LONGINT; var result: AppleEvent): OSErr;
inline
$303C, $0B14, $A816;
function AESend (theAppleEvent: AppleEvent; var reply: AppleEvent; sendMode: AESendMode; sendPriority: AESendPriority; timeOutInTicks: LONGINT; idleProc: ProcPtr; filterProc: ProcPtr): OSErr;
inline
$303C, $0D17, $A816;
var
theDoomed: AEAddressDesc; {PSN descriptor of process to be terminated}
quitEvent: AppleEvent; {'quit' AppleEvent}
reply: AppleEvent; {Reply from receiving application; ignored}
error: OSErr;
procedure RecoverError (error: Integer);
var
result: OSErr;
begin
if theDoomed.dataHandle <> nil then
result := AEDisposeDesc(theDoomed);(*◊*)
if quitEvent.dataHandle <> nil then
result := AEDisposeDesc(quitEvent);(*◊*)
TerminateProcess := error;
EXIT(TerminateProcess)
end;
begin
theDoomed.dataHandle := nil;
quitEvent.dataHandle := nil;
reply.dataHandle := nil;
(* Create the Process Serial Number event descriptor *)
error := AECreateDesc(typeProcessSerialNumber, Ptr(@theProcessNum), SIZEOF(theProcessNum), theDoomed); (*<*)
if error <> noErr then
RecoverError(error);
(* Create 'quit' event with the specified process serial number *)
error := AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, theDoomed, kAutoGenerateReturnID, kAnyTransactionID, quitEvent); (*<*)
if error <> noErr then
RecoverError(error);
(* Send the 'quit' event *)
error := AESend(quitEvent, reply, kAENoReply, kAENormalPriority, kNoTimeOut, nil, nil); (*<*)
if error <> noErr then
RecoverError(error);
(* PSN in the AppleEvent, so can dispose of PSN descriptor *)
error := AEDisposeDesc(theDoomed);(*◊*)
(* Dispose of the 'quit' AppleEvent *)
error := AEDisposeDesc(quitEvent)(*◊*)
end;
{Step through the process list and fill in our process list arrays and the menus}
procedure UpdateProcessList;
var
i, length: Integer;
begin
{Remove all old menu items}
length := CountMItems(infoMenu);
for i := 1 to length do
DelMenuItem(infoMenu, 1);
length := CountMItems(switchMenu);
for i := 1 to length do
DelMenuItem(switchMenu, 1);
length := CountMItems(terminateMenu);
for i := 1 to length do
DelMenuItem(terminateMenu, 1);
{Step through the process list}
PSN.highLongOfPSN := 0;
PSN.lowLongOfPSN := kNoProcess;
iErr := GetNextProcess(PSN);
numProc := 0;
while iErr = noErr do
begin
numProc := numProc + 1;
psnList[numProc] := PSN;
pInfo[numProc].processInfoLength := SIZEOF(ProcessInfoRec);
pInfo[numProc].processName := @procName[numProc];
pInfo[numProc].processAppSpec := nil;
if noErr = GetProcessInformation(PSN, pInfo[numProc]) then
begin
AppendMenu(infoMenu, pInfo[numProc].processName^);
AppendMenu(switchMenu, pInfo[numProc].processName^);
AppendMenu(terminateMenu, pInfo[numProc].processName^);
end;
iErr := GetNextProcess(PSN);
end;
end;
procedure DoFileMenu (item: integer);
begin
case item of
1:
UpdateProcessList;
3:
SkelWhoa; { Tell SkelMain to quit }
end; {case}
end;
procedure DoInfoMenu (item: integer);
begin
ShowWindow(w);
SelectWindow(w);
curProc := item;
SetPort(w);
InvalRect(w^.portRect);
end;
procedure DoSwitchMenu (item: integer);
begin
iErr := SetFrontProcess(psnList[item]);
end;
procedure DoTerminateMenu (item: integer);
begin
iErr := TerminateProcess(psnList[item]);
UpdateProcessList;
end;
procedure Mouse (thePt: Point; t: longint; mods: integer);
begin
end;
procedure Idle;
begin
end;
procedure Update (resized: Boolean);
function MyNumToString (l: Longint): Str255;
var
s: Str255;
begin
NumToString(l, s);
MyNumToString := s;
end;
begin
EraseRect(w^.portRect);
MoveTo(10, 20);
DrawString(pInfo[curProc].processName^);
MoveTo(10, 40);
DrawString(stringof('Type: ', OSType(pInfo[curProc].processType)));
MoveTo(10, 60);
DrawString(stringof('Type: ', pInfo[curProc].processSignature));
MoveTo(10, 80);
DrawString(stringof('Size: ', pInfo[curProc].processSize div 1024, 'k'));
MoveTo(10, 100);
DrawString(stringof('Free memory: ', pInfo[curProc].processFreeMem div 1024, 'k'));
end;
procedure Key (ch: char; mods: integer);
begin
end;
begin
SkelInit(6, nil); { Initialize }
SkelApple('(Om ProcPuppy…', @About); { Handle Desk Accessories }
m := NewMenu(2, 'File'); { Create Menu }
AppendMenu(m, 'Update process list/P;(-;Quit/Q');
dummy := SkelMenu(m, @DoFileMenu, nil, true); { Tell Transkel to handle it }
infoMenu := NewMenu(3, 'Info'); { Create Menu }
switchMenu := NewMenu(4, 'Switch'); { Create Menu }
terminateMenu := NewMenu(5, 'Terminate'); { Create Menu }
UpdateProcessList; {Update list and fill menus}
dummy := SkelMenu(infoMenu, @DoInfoMenu, nil, true); { Tell Transkel to handle it }
dummy := SkelMenu(switchMenu, @DoSwitchMenu, nil, true); { Tell Transkel to handle it }
dummy := SkelMenu(terminateMenu, @DoTerminateMenu, nil, true); { Tell Transkel to handle it }
curProc := 1;
r.top := 50;
r.left := 20;
r.bottom := 200;
r.right := 250;
w := NewCWindow(nil, r, 'ProcPuppy', true, documentProc, WindowPtr(-1), true, 0);
SetPort(w);
dummy := SkelWindow(w, @Mouse, @Key, @Update, nil, nil, nil, @Idle, true);
SkelMain; { loop til quit selected }
SkelClobber; { clean up }
end.